#include <iostream>
#include <fstream>
#include <istream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;


int main()
{
  int listen_sock = socket(AF_INET , SOCK_STREAM , 0);
  if (listen_sock < 0)
  {
    cerr << "socket error" << endl;
    exit(1);
  }

  struct sockaddr_in local;
  memset(&local , '\0' , sizeof(local));
  local.sin_family = AF_INET;
  local.sin_port = htons(8081);
  local.sin_addr.s_addr = htonl(INADDR_ANY);
  if (bind(listen_sock , (struct sockaddr*)&local , sizeof(local)) < 0 )
  {
    cerr << "bind error" << endl;
    exit(2);
  }


  if (listen(listen_sock , 5) < 0)
  {
    cerr << "listen error" << endl;
    exit(3);
  }

  struct sockaddr_in peer;
  memset(&peer , '\0' , sizeof(peer));
  socklen_t len;

  for(;;)
  {
    int sock = accept(listen_sock , (struct sockaddr*)&peer , &len);
    if (sock < 0)
    {
      cerr << "accept error" << endl;
      continue;
    }

    if (fork() == 0)
    {
      // father 
      close(listen_sock);
      if (fork() > 0)
      {
        // father
        exit(0);
      }
      
      // child 
      char buff[1024];
      recv(sock , buff , sizeof(buff) , 0);


      cout << "-------- -------- http request begin -------" << endl;
      cout << buff << endl;
      cout << "-------- -------- http request end   -------" << endl;

#define WWWROOT "./wwwroot"
#define PAGE "index.html"
      ifstream in(PAGE);
     
      
      
      if (in.is_open())
      {
        in.seekg(0 , in.end);
        int len = in.tellg();
        in.seekg(0 , in.beg);
        char* file = new char[len];
        in.read(file , len);
        in.close();


        string status_line = "http/1.1 200 OK\n"; // line  
        
        string response_header = "Content-length:" + to_string(len) + "\n"; // line head 
        string blank = "\n";
        string response_text = file;
        string response = status_line + response_header + blank + response_text;
       
        send(sock , response.c_str() , response.size() , 0);

        delete[] file;

      }

      close(sock);
      exit(0);
    }


    close(sock);
    waitpid(-1 , nullptr , 0);
  }


  return 0;
}

